package com.chen10.cattle.service.impl;

import com.chen10.cattle.common.constants.GameConstants;
import com.chen10.cattle.common.constants.RedisKeyConstants;
import com.chen10.cattle.common.constants.WsEventConstants;
import com.chen10.cattle.common.enums.game.RoomPlayerStatus;
import com.chen10.cattle.common.enums.game.RoomStatusEnums;
import com.chen10.cattle.common.enums.response.ErrorEnum;
import com.chen10.cattle.common.exception.BusinessException;
import com.chen10.cattle.common.utils.RedisUtil;
import com.chen10.cattle.mapper.UserMapper;
import com.chen10.cattle.model.dto.MatchDTO;
import com.chen10.cattle.model.vo.PlayerInfoVO;
import com.chen10.cattle.model.vo.UserInfoVO;
import com.chen10.cattle.service.MatchFightService;
import com.chen10.cattle.ws.WebSocketHandler;
import com.chen10.cattle.ws.pojo.Room;
import com.chen10.cattle.ws.pojo.WsMessage;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Service
public class MatchFightServiceImpl implements MatchFightService {
    private static final Map<Integer, Integer> matchUsers = new ConcurrentHashMap<>();
    @Resource
    public RestTemplate restTemplate;
    @Resource
    private WebSocketHandler webSocketHandler;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private UserMapper userMapper;
    @Override
    public void matchSuccess(MultiValueMap<String, String> matchData) {
        if(matchData == null){
            throw new BusinessException(ErrorEnum.PARAM_ERROR);
        }
        // 解析matchData
        Integer player1 = Integer.valueOf(matchData.get("a_id").get(0));
        Integer player2 = Integer.valueOf(matchData.get("b_id").get(0));

        //生成roomId
        String roomId = GameConstants.ROOM_KEY_BY_USERID_PREFIX + player1 + "_" + player1;
        //初始化玩家信息
        List<PlayerInfoVO> playerInfoVos = new ArrayList<>();
        PlayerInfoVO playerInfoVO1 = getPlayerInfo(player1);
        PlayerInfoVO playerInfoVO2 = getPlayerInfo(player2);
        playerInfoVO1.setReadyStatus(RoomPlayerStatus.READY.getCode());
        playerInfoVO2.setReadyStatus(RoomPlayerStatus.READY.getCode());
        playerInfoVos.add(playerInfoVO1);
        playerInfoVos.add(playerInfoVO2);

        //初始化房间信息
        Room room = new Room();
        room.setRoomId(roomId);
        room.setPlayerInfoList(playerInfoVos); // 使用新的可变列表
        room.setStatus(RoomStatusEnums.PLAYING.getDesc());
        room.setMatchMode(true);
        room.initGame();

        //更新redis
        redisUtil.set(RedisKeyConstants.REDIS_ROOM_KEY_PREFIX + roomId, room);
        //插入一个数据，记录游戏步数数据
        redisUtil.set(RedisKeyConstants.REDIS_GAME_DATA_KEY_PREFIX + roomId,"");
        //为房间的用户存一个roomId
        redisUtil.set(RedisKeyConstants.REDIS_USERS_ROOM_ID_KEY_PREFIX + player1 , roomId);
        redisUtil.set(RedisKeyConstants.REDIS_USERS_ROOM_ID_KEY_PREFIX + player2 , roomId);

        //发消息给两个玩家
        WsMessage<Room> matchMessage = new WsMessage<>();
        matchMessage.setData(room);
        matchMessage.setSenderId(-666);
        matchMessage.setEvent(WsEventConstants.MATCH_FIGHT_SUCCESS);
        matchMessage.setTimestamp(System.currentTimeMillis());

        webSocketHandler.sendMessageToUser(player1, matchMessage);
        webSocketHandler.sendMessageToUser(player2, matchMessage);

        //删除队列
        matchUsers.remove(player1);
        matchUsers.remove(player2);

    }

    /**
     * 匹配
     * @param matchDTO
     * @return
     */
    @Override
    public String match(MatchDTO matchDTO) {
        if(matchDTO == null){
            throw new BusinessException(ErrorEnum.PARAM_ERROR);
        }
        Integer userId = matchDTO.getUserId();
        if(matchUsers.get(userId)!=null){
            throw new BusinessException(ErrorEnum.USER_IS_MATCHING);
        }
        matchUsers.put(userId, matchDTO.getRating());

        //调用匹配接口
        MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
        data.add("user_id",matchDTO.getUserId().toString());
        data.add("rating",matchDTO.getRating().toString());
        data.add("bot_id","1");

        String addPlayerUrl = "http://127.0.0.1:3031/player/add/";

        return restTemplate.postForObject(addPlayerUrl,data,String.class);
    }

    /**
     * 取消匹配
     * @param matchDTO
     * @return
     */
    @Override
    public String cancelMatch(MatchDTO matchDTO) {
        if(matchDTO == null){
            throw new BusinessException(ErrorEnum.PARAM_ERROR);
        }
        Integer userId = matchDTO.getUserId();
        Integer rating = matchDTO.getRating();
        if(matchUsers.get(userId)==null){
            throw new BusinessException(ErrorEnum.USER_IS_NOT_MATCHING);
        }
        matchUsers.remove(userId,rating);
        //调用匹配接口
        MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
        data.add("user_id",matchDTO.getUserId().toString());

        String addPlayerUrl = "http://127.0.0.1:3031/player/remove/";


        return restTemplate.postForObject(addPlayerUrl,data,String.class);
    }


    /**
     * 获取玩家信息
     * @param userId
     * @return
     */
    private PlayerInfoVO getPlayerInfo(Integer userId){
        //查询缓存
        PlayerInfoVO playerInfoVO = (PlayerInfoVO) redisUtil.get(RedisKeyConstants.REDIS_PLAYER_INFO_KEY_PREFIX + userId);
        if(playerInfoVO == null){
            //查询数据库用户信息
            UserInfoVO userInfoVO = userMapper.getUserInfoById(userId);

            playerInfoVO = new PlayerInfoVO();
            playerInfoVO.setUserId(userId);
            playerInfoVO.setUsername(userInfoVO.getUsername());
            playerInfoVO.setAvatarUrl(userInfoVO.getAvatarUrl());
            playerInfoVO.setReadyStatus(RoomPlayerStatus.UNREADY.getCode());
            //缓存玩家信息
            redisUtil.setex(RedisKeyConstants.REDIS_PLAYER_INFO_KEY_PREFIX + userId,playerInfoVO, 30, TimeUnit.MINUTES);
        }
        return playerInfoVO;
    }

    /**
     * 从 matchUsers 中移除指定用户 ID 的条目。
     *
     * @param userId 用户 ID
     */
    public static void removeUserFromMatchUsers(Integer userId) {
        matchUsers.remove(userId);
    }

    /**
     * 从 matchUsers 中移除指定用户 ID 的条目。
     *
     * @param userId 用户 ID
     * @return
     */
    public static boolean isUserInMatching(Integer userId) {
        return matchUsers.get(userId) != null;
    }
}
